import * as vscode from "vscode";
import * as fs from 'fs';
import * as path from 'path';
import {
    setCopyText,
    getLocale,
    addEventListener,
    updateText,
    getPosition,
  } from "@vscode-use/utils";
import { DocLinterWebviewRequestHandler } from "../plugins/actions/DocLinter/docLinterWebviewRequestHandler";
import { LoginService } from "./services/loginService";

export class DocLinterGUIWebviewViewProvider implements vscode.WebviewViewProvider {
  private _view?: vscode.WebviewView;
  private _webview?: vscode.Webview;

  getWebview(): vscode.Webview {
    return this._webview!;
  }

  constructor(
    private readonly _extensionUri: vscode.Uri,
    private readonly _mode: vscode.ExtensionMode,
    private context: vscode.ExtensionContext,
  ) {
  }

  resolveWebviewView(webviewView: vscode.WebviewView) {
    this._webview = webviewView.webview;
    this._view = webviewView;
    webviewView.webview.options = {
      // 在 webview 允许脚本
      enableScripts: true,
      localResourceRoots: [this._extensionUri],
    };

    const inDevelopmentMode = this._mode === vscode.ExtensionMode.Development;
    if (!inDevelopmentMode) {
      webviewView.webview.html = this.getProductionHtml(webviewView.webview);
    } else {
      webviewView.webview.html = this.getDebugHtml(webviewView.webview);
    }

    const docLinterWebviewRequestHandler = new DocLinterWebviewRequestHandler(this.context, this._webview, this._webview);

    webviewView.webview.onDidReceiveMessage(
        async (message) => {
            switch (message.type) {
                case "login":
                    docLinterWebviewRequestHandler.login();
                    break;
                case "themeCallback":
                    break;
                case "queryHasLogin":
                    docLinterWebviewRequestHandler.queryHasLogin();
                    break;
                case "fetchRecord":
                    docLinterWebviewRequestHandler.fetchRecord(message.data);
                    break;
                case "viewReport":
                    docLinterWebviewRequestHandler.viewReport(message.data);
                    break;
                case "lang":
                    docLinterWebviewRequestHandler.getlangunage();
                    break;
                case "goToFile":
                    docLinterWebviewRequestHandler.goToFile(message.data.filePath, message.data.line);
                    break;
                case "compare":
                    docLinterWebviewRequestHandler.compare(message.data.filePath, message.data.line, message.data.originText, message.data.fixText);
                    break;
                case "copy":
                    docLinterWebviewRequestHandler.copy(message.data);
                    break;
                case "replace":
                    await docLinterWebviewRequestHandler.replace(message.data.filePath, message.data.line, message.data.originText, message.data.fixText);
                    break;
                case "raise":
                    docLinterWebviewRequestHandler.raise(message.data.status, message.data.reportId, message.data.defectId, message.data.reason);
                    break;
                case "openExternal":
                  const urls = {
                    DEV: process.env.DEV_DOCLINTER_REPORT_URL!,
                    BETA: process.env.BETA_DOCLINTER_REPORT_URL!,
                    TEST: process.env.TEST_DOCLINTER_REPORT_URL!,
                    PROD: process.env.PROD_DOCLINTER_REPORT_URL!
                  };
                    const reportId = message.data;
                    const env = (process.env.enviroment || 'DEV').toUpperCase();
                    const url = `${urls[env as keyof typeof urls]}/workbench/ai/docLinter/viewReport?reportId=${reportId}`;
                    docLinterWebviewRequestHandler.openExternal(url);
                    break;
                case "cancel":
                    docLinterWebviewRequestHandler.cancel(message.data);
                    break;
                case "logOut":
                    LoginService.getInstance(this.context).logout();
                    break;
            }
        },
        undefined,
        this.context.subscriptions
      );
      addEventListener("theme-change", (e) => {
        this._view?.webview.postMessage({
          type: "themeCallback",
          data: e.kind,
        });
      });
  }

  /**
   * 更新登录状态
   */
  public async updateLoginStatus() {
    const isLoggedIn = await LoginService.getInstance(this.context).isLoggedIn();
    if (isLoggedIn) {
      const userInfo = await LoginService.getInstance(this.context).getUserInfo();
      this._webview?.postMessage({
        type: "queryHasLoginCallback",
        data: {
            name: userInfo?.cnName
        }
      });
    } else {
      this._webview?.postMessage({
        type: "logOutCallback",
        data: true
      });
    }
  }

  getDebugHtml(webview: vscode.Webview) {
    const code = fs.readFileSync(
      path.resolve(this._extensionUri.fsPath, "webview_ui_docLinter/dist/index.html"),
      "utf-8"
    );
    const files = fs.readdirSync(
      path.resolve(this._extensionUri.fsPath, "webview_ui_docLinter/dist/assets")
    );
    let jsFile = "";
    let cssFile = "";
    for (const file of files) {
      if (file.endsWith("js")) {
        jsFile = file;
      } else if (file.endsWith("css")) {
        cssFile = file;
      } else {
      }
    }
    const curPath = vscode.Uri.joinPath(
      this._extensionUri,
      "webview_ui_docLinter/dist/assets",
      jsFile
    );
    const curCssPath = vscode.Uri.joinPath(
      this._extensionUri,
      "webview_ui_docLinter/dist/assets",
      cssFile
    );
    const jsSrc = this._webview?.asWebviewUri(curPath);
    const cssSrc = this._webview?.asWebviewUri(curCssPath);
    let result = code.replace(/<script.*?src="(.*?)">/g, (curStr: string) => {
      return curStr.replace(/src="(.+?)"/, (src: string) => {
        return `src="${jsSrc}"`;
      });
    });
    result = result.replace(/<link.*?href="(.*?)">/g, (curStr: string) => {
      return curStr.replace(/href="(.+?)"/, (src: string) => {
        return `href="${cssSrc}"`;
      });
    });
    
    return result;
  }

  getProductionHtml(webview: vscode.Webview) {
    const code = fs.readFileSync(
      path.resolve(this._extensionUri.fsPath, "webview_ui_docLinter/dist/index.html"),
      "utf-8"
    );
    const files = fs.readdirSync(
      path.resolve(this._extensionUri.fsPath, "webview_ui_docLinter/dist/assets")
    );
    let jsFile = "";
    let cssFile = "";
    for (const file of files) {
      if (file.endsWith("js")) {
        jsFile = file;
      } else if (file.endsWith("css")) {
        cssFile = file;
      } else {
      }
    }
    const curPath = vscode.Uri.joinPath(
      this._extensionUri,
      "webview_ui_docLinter/dist/assets",
      jsFile
    );
    const curCssPath = vscode.Uri.joinPath(
      this._extensionUri,
      "webview_ui_docLinter/dist/assets",
      cssFile
    );
    const jsSrc = this._webview?.asWebviewUri(curPath);
    const cssSrc = this._webview?.asWebviewUri(curCssPath);
    let result = code.replace(/<script.*?src="(.*?)">/g, (curStr: string) => {
      return curStr.replace(/src="(.+?)"/, (src: string) => {
        return `src="${jsSrc}"`;
      });
    });
    result = result.replace(/<link.*?href="(.*?)">/g, (curStr: string) => {
      return curStr.replace(/href="(.+?)"/, (src: string) => {
        return `href="${cssSrc}"`;
      });
    });
    
    return result;
  }
} 